package com.luck.pf.security.menu.logic;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.jdbc.core.RowMapper;

import com.luck.org.entity.SysLog;
import com.luck.org.entity.SysMenu;
import com.luck.org.entity.SysUser;
import com.luck.pf.common.entity.UserBean;
import com.luck.pf.framework.dao.BaseJdbcDao;
import com.luck.pf.framework.logic.BaseLogic;
import com.luck.pf.security.menu.qry.MenuQry;

/**
 * 说明:
 * Copyright: Copyright (c) 2010
 * @author zhangwr 2011-8-10 下午02:40:13
 * @version 1.0
 */
public class MenuLogic extends BaseLogic implements IMenuLogic {
	
	private BaseJdbcDao jdbcDao;
	
	public SysUser findUserByLoginname(String loginname){
		List<SysUser> list = super.baseDao.find(" FROM SysUser WHERE loginname=?",loginname);
		if(null != list && !list.isEmpty())
			return list.get(0);
		return null;
	}
	public List<SysMenu> findAuthMenu(MenuQry qry) {
		List<SysMenu> menus = new ArrayList<SysMenu>();
		if(qry.getIsInitLoad().equals("1")){
			Criteria criteria = super.baseDao.createCriteria(SysMenu.class);
			criteria.add(Restrictions.ne("isFilter", "0"));
			menus = criteria.list();
		}else{
			if(qry.getUserInfo().getUserId()==1L){
				Criteria criteria = super.baseDao.createCriteria(SysMenu.class);
				criteria.addOrder(Order.asc("treeNo"));
				menus = criteria.list();
			}else{
				menus = findUserAuthIds(qry.getUserInfo().getUserId());
			}
		}
		return menus;
	}
	public List<Long> findUserAuth(String loginname) {
		List<Long> ls = new ArrayList<Long>();
		SysUser user = findUserByLoginname(loginname);
		if(user == null)
			return ls;
		List<SysMenu> menus = findUserAuthIds(user.getId());
		for(SysMenu menu:menus){
			if(StringUtils.isNotBlank(menu.getUrl()))
				ls.add(menu.getId());
		}
		return ls;
	}
	/**
	 * 根据角色id,读取所有权限菜单
	 */
	public List<SysMenu> findAuthByRoleId(Long roleId) {
		StringBuffer sql =new StringBuffer();
		Map params = new HashMap();
		sql.append("select m.* from sys_menu m where m.id in( select rm.menu_id from sys_role_menu rm where rm.role_id =:roleId)");
		params.put("roleId", roleId);
		List<SysMenu> menus = jdbcDao.queryForList(sql.toString(),params,menuRw);
		return menus;
	}

	/**
	 * 得到此用户所有权限
	 * @param loginname
	 * @return
	 */
	public List<SysMenu> findUserAuthIds(Long userId) {
		StringBuffer sql =new StringBuffer();
		Map params = new HashMap();
		sql.append("select m.* from sys_menu m,( select rm.menu_id from sys_role_menu rm where rm.role_id in(select ur.role_id from sys_user_role ur where ur.user_id=:userId )) a where m.id=a.menu_id order by m.tree_no");
		params.put("userId", userId);
		List<SysMenu> menus = jdbcDao.queryForList(sql.toString(),params,menuRw);
		return menus;
	}

	private final MenuRw menuRw = new MenuRw();
	private static final class MenuRw implements RowMapper{
		public Object mapRow(ResultSet rs, int rownum) throws SQLException {
			SysMenu menu = new SysMenu();
			menu.setId(rs.getLong("id"));
			menu.setMenuLevel(rs.getString("menu_level"));
			menu.setParentId(rs.getLong("parent_id"));
			menu.setResItemId(rs.getString("res_item_id"));
			menu.setRootFlag(rs.getString("root_flag"));
			menu.setMenuName(rs.getString("menu_name"));
			menu.setUrl(rs.getString("url"));
			menu.setIsLeaf(rs.getString("is_leaf"));
			menu.setIsView(rs.getString("is_view"));
			//System.out.println(rs.getString("is_view"));
			return menu;
		}
		
	}
	public List<SysMenu> findUserMenu(String loginname,String systemFlag, String userFlag) {
		List<SysMenu> result = new ArrayList<SysMenu>();
		SysUser user = findUserByLoginname(loginname);
		if(user == null)
			return result;
		List<SysMenu> allMenus = findUserAuthIds(user.getId());
		List<SysMenu> flagMenus = findMenuByFlag(systemFlag,userFlag);
		for(SysMenu menu:allMenus){
			for(SysMenu flag:flagMenus){
				//if(menu.getId().equals(flag.getId()) && flag.getIsView().equals("1")){
				if(menu.getIsView().equals("1") && menu.getId().equals(flag.getId())){
					result.add(flag);
					break;
				}
			}
		}
		return result;
	}
	/**
	 * 查询出此用户具有的菜单，根据flag
	 * @param sysflag系统启动时设置的菜单权限,根菜单：ROOT,后台管理ROOT_ORG,业务对象:ROOT_RES,前台应用:ROOT_BS
	 * @param userFlag用户资料设置的权限
	 * @return
	 */
	public List<SysMenu> findMenuByFlag(String systemFlag, String userFlag){
		String sysTreeNo="",userTreeNo="" ,resTreeNo="";
		//计算出业务权限resTreeNo
		List<SysMenu> resList = super.baseDao.find(" FROM SysMenu WHERE rootFlag='ROOT_RES'");
		SysMenu resMenu = resList.get(0);
		resTreeNo=resMenu.getTreeNo();
		
		//如果系统标志与用户标志都是ROOT_RES,则读所有业务资源菜单
		if(systemFlag == "ROOT_RES" && userFlag == "ROOT_RES"){
			return super.baseDao.find(" FROM SysMenu WHERE treeNo like ? ",new Object[]{resTreeNo+"%"});
		}
		//计算系统标识
		List<SysMenu> sysList = super.baseDao.find(" FROM SysMenu WHERE rootFlag=?",systemFlag);
		SysMenu sysMenu = sysList.get(0);
		sysTreeNo=sysMenu.getTreeNo();
		
		//计算用户标识
		List<SysMenu> userList = super.baseDao.find(" FROM SysMenu WHERE rootFlag=?",userFlag);
		SysMenu userMenu = userList.get(0);
		userTreeNo=userMenu.getTreeNo();
		
		//读出系统与用户权限的合集菜单，并不包括业务权限的菜单 
		return super.baseDao.find(" FROM SysMenu WHERE treeNo like ? and treeNo like ? and treeNo not like ?",new Object[]{sysTreeNo+"%", userTreeNo+"%",resTreeNo+"%"});
	}
	public SysMenu saveMenu(SysMenu menu) throws Exception{
		StringBuffer bf = new StringBuffer();
		SysMenu parent = super.baseDao.get(SysMenu.class, menu.getParentId());
		if(menu.getId() == null){
			menu.setTreeNo(generatorTreeNo(parent));
		}
		if(StringUtils.isBlank(menu.getResItemId()) && menu.getIsLeaf().equals("0") && StringUtils.isBlank(menu.getUrl()))
			bf.append("不是叶子节点时请填写URL");
		if(StringUtils.isNotBlank(bf.toString()))
			throw new Exception(bf.toString());
		super.baseDao.save(menu);
		return menu;
	}
	private String generatorTreeNo(SysMenu parent) {
		List list = baseDao.find(" SELECT max(treeNo) FROM SysMenu WHERE parentId=?",parent.getId());
		if(list == null ||list.isEmpty()){
			return parent.getTreeNo()+"001";
		}else{
			String treeno = (String) list.get(0);
			if(StringUtils.isBlank(treeno))
				return parent.getTreeNo()+"001";
			else{
				Long no = new Long(treeno);
				return (no+1)+"";
			}
		}
	}
	public String deleteMenu(SysMenu menu,UserBean userBean, SysLog log) throws Exception{
		StringBuffer bf = new StringBuffer();
		if(!userBean.getUser().getUserLevel().equals("1"))
			bf.append("您不是管理员<br/>");
		if(!userBean.getDept().getDeptLevel().equals("1"))
			bf.append("您不是顶级机构成员<br/>");
		if(menu.getParentId() == null)
			bf.append("此为根菜单<br/>");
		int sons = baseDao.count(" select count(*) FROM SysMenu WHERE parentId=?",menu.getId());
		if(sons > 0)
			bf.append("此菜单下有子菜单<br/>");
		if(StringUtils.isBlank(bf.toString())){
			super.delete(menu);
		}else
			throw new Exception(bf.toString());
		return bf.toString();
	}
	public BaseJdbcDao getJdbcDao() {
		return jdbcDao;
	}

	public void setJdbcDao(BaseJdbcDao jdbcDao) {
		this.jdbcDao = jdbcDao;
	}
	
}
